home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / IrComm Remote / DiscRemote / Src / DiscRemote.c next >
Text File  |  1999-06-25  |  15KB  |  640 lines

  1. /*    ===========================================================================
  2.     Most code derived from demo code received from Smartcode Software, Inc.
  3.     ===========================================================================    */
  4.  
  5. #include <Pilot.h>
  6. #include <SysEvtMgr.h>
  7. #include <StringMgr.h>
  8. #include <FeatureMgr.h>
  9. #include <SerialMgr.h>
  10. #include <SerialMgrNew.h>
  11.  
  12. #include "DiscRemoteRes.h"
  13. #include "CommandStrings.h"
  14.  
  15. // Comment out if compiling for the old serial manager
  16. // FIXME: Need to query for new serial manager and dynamically use correct calls?
  17.  
  18.  
  19. /* ---------------------------------------------------------------------------    */
  20.  
  21. #define version30        0x03000000    // PalmOS 3.0 version number
  22.  
  23. /* ---------------------------------------------------------------------------    */
  24.  
  25. static UInt16            gRefNum;
  26. static UInt32            gUseNewSerialManager;
  27. static Char                gTestBuffer[4096];
  28.  
  29. /* ---------------------------------------------------------------------------    */
  30.  
  31. //#define kSerialLibName        "SerIrCOMM Lib"
  32. #define kSerialLibName        "Serial Library"
  33.  
  34. static Err PrvSerLibFind(UInt16* refNumP)
  35. {
  36.     if (gUseNewSerialManager) {
  37.         *refNumP = 0x1234;
  38.         return 0;
  39.     }
  40.     else {
  41.         return SysLibFind(kSerialLibName, refNumP);
  42.     }
  43. }
  44.  
  45. /* ---------------------------------------------------------------------------    */
  46.  
  47. static Err PrvSerOpen(UInt16 refNum, UInt32 portId, UInt32 baud, UInt16* newPortP)
  48. {
  49.     if (gUseNewSerialManager) {
  50.         return SrmOpen(portId, baud, newPortP);
  51.     }
  52.     else {
  53.         return SerOpen(refNum, 0, baud);
  54.     }
  55. }
  56.  
  57. /* ---------------------------------------------------------------------------    */
  58.  
  59. static Err PrvSerClose(UInt16 refNum)
  60. {
  61.     if (gUseNewSerialManager) {
  62.         return SrmClose(refNum);
  63.     }
  64.     else {
  65.         return SerClose(refNum);
  66.     }
  67. }
  68.  
  69. /* ---------------------------------------------------------------------------    */
  70.  
  71. static Err PrvSerReceiveCheck(UInt16 refNum, UInt32* numBytesP)
  72. {
  73.     if (gUseNewSerialManager) {
  74.         return SrmReceiveCheck(refNum, numBytesP);
  75.     }
  76.     else {
  77.         return SerReceiveCheck(refNum, numBytesP);
  78.     }
  79. }
  80.  
  81. /* ---------------------------------------------------------------------------    */
  82.  
  83. static UInt32 PrvSerReceive(UInt16 refNum, void* rcvBufP, UInt32 count, Int32 timeout, Err* errP)
  84. {
  85.     if (gUseNewSerialManager) {
  86.         return SrmReceive(refNum, rcvBufP, count, timeout, errP);
  87.     }
  88.     else {
  89.         return SerReceive(refNum, rcvBufP, count, timeout, errP);
  90.     }
  91. }
  92.  
  93. /* ---------------------------------------------------------------------------    */
  94.  
  95. static UInt32 PrvSerSend (UInt16 refNum, void* sndBufP, UInt32 count, Err* errP)
  96. {
  97.     if (gUseNewSerialManager) {
  98.         return SrmSend(refNum, sndBufP, count, errP);
  99.     }
  100.     else {
  101.         return SerSend(refNum, sndBufP, count, errP);
  102.     }
  103. }
  104.  
  105. /* ---------------------------------------------------------------------------    */
  106.  
  107. static void* GetObjectPtr(UInt16 id)
  108. {
  109.     FormPtr form = FrmGetActiveForm();
  110.     return FrmGetObjectPtr(form, FrmGetObjectIndex(form, id));
  111. }
  112.  
  113. /* ---------------------------------------------------------------------------    */
  114.  
  115. static void UpdateScrollBar(UInt16 textID, UInt16 scrollBarID)
  116. {
  117.     UInt16             scrollPos;
  118.     UInt16             textHeight;
  119.     UInt16             fieldHeight;
  120.     Int16             maxValue;
  121.     FieldPtr         textField;
  122.     ScrollBarPtr    scrollBar;
  123.  
  124.     textField = GetObjectPtr(textID);
  125.     scrollBar = GetObjectPtr(scrollBarID);
  126.     
  127.     FldGetScrollValues(textField, &scrollPos, &textHeight, &fieldHeight);
  128.  
  129.     if (textHeight > fieldHeight)
  130.         maxValue = textHeight - fieldHeight;
  131.     else
  132.         maxValue = scrollPos;
  133.  
  134.     if (scrollPos > maxValue)
  135.         scrollPos = maxValue;
  136.         
  137.     SclSetScrollBar(scrollBar, scrollPos, 0, maxValue, fieldHeight - 1);
  138. }
  139.  
  140. /* ---------------------------------------------------------------------------    */
  141.  
  142. static void HandleTextScroll(Int16 linesToScroll, UInt16 textID, UInt16 scrollBarID)
  143. {
  144.     UInt16            blankLines;
  145.     FieldPtr        textField;
  146.     UInt16            scroll;
  147.     
  148.     textField = GetObjectPtr(textID);
  149.  
  150.     if (linesToScroll < 0)  {
  151.         blankLines = FldGetNumberOfBlankLines(textField);
  152.         linesToScroll = -linesToScroll;
  153.         
  154.         scroll = (blankLines > linesToScroll) ? blankLines : linesToScroll;
  155.         FldScrollField(textField, scroll, winUp);
  156.         
  157.         //    If there were blank lines visible at the end of the field
  158.         //    then we need to update the scroll bar.
  159.         if (blankLines >= linesToScroll)
  160.             UpdateScrollBar(textID, scrollBarID);
  161.         
  162.     } 
  163.     else 
  164.         if (linesToScroll > 0)
  165.             FldScrollField(textField, linesToScroll, winDown);
  166. }
  167.  
  168.  
  169. /* ---------------------------------------------------------------------------    */
  170.  
  171. static Boolean SetEditFieldText(FormPtr form, UInt16 id, UInt8* text, UInt16 size)
  172. {
  173.     UInt8*        textP;
  174.     VoidHand    textH = 0;
  175.     VoidHand    hand;
  176.     FieldPtr    field;
  177.     
  178.     form = (form == 0) ? FrmGetActiveForm() : form;
  179.     field = FrmGetObjectPtr(form, FrmGetObjectIndex(form, id));
  180.     if (size > 0)
  181.     {
  182.         textH = MemHandleNew(size + 1);
  183.         if (textH == 0)
  184.             return false;
  185.  
  186.         textP = MemHandleLock(textH);
  187.         if (text != 0)
  188.             MemMove(textP, text, size);
  189.         textP[size] = 0;
  190.         MemHandleUnlock(textH);
  191.     }
  192.     
  193.     hand = FldGetTextHandle(field);
  194.     FldSetTextHandle(field, 0);
  195.     if (hand != 0)
  196.         MemHandleFree(hand);
  197.     
  198.     FldSetTextHandle(field, textH);
  199.     return true;
  200. }
  201.  
  202. /* ---------------------------------------------------------------------------    */
  203.  
  204. static Boolean AppendEditFieldText(UInt16 id, UInt8 *text, UInt16 size)
  205. {
  206.     UInt8*        textP;
  207.     VoidHand    textH;
  208.     FieldPtr    field;
  209.     UInt32        length = -1;
  210.     
  211.     field = GetObjectPtr(id);
  212.     textH = FldGetTextHandle(field);
  213.     if (textH == 0) {
  214.         textH = MemHandleNew(size + 1);
  215.         length = 0;
  216.     }
  217.     else 
  218.     {
  219.         FldSetTextHandle(field, 0);
  220.         if (MemHandleResize(textH, MemHandleSize(textH) + size) != 0) 
  221.         {
  222.             FldSetTextHandle(field, textH);
  223.             textH = 0;
  224.         }
  225.     }
  226.         
  227.     if (textH == 0)
  228.         return false;
  229.  
  230.     textP = MemHandleLock(textH);
  231.     if (length == -1)
  232.         length = StrLen((char*)textP);
  233.     MemMove(&textP[length], text, size);
  234.     textP[length + size] = 0;
  235.     MemHandleUnlock(textH);
  236.  
  237.     FldSetTextHandle(field, textH);
  238.     return true;
  239. }
  240.  
  241. /* ---------------------------------------------------------------------------    */
  242.  
  243. static Err AppRomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags)
  244. {
  245.     UInt32 romVersion;
  246.         
  247.     // See if we're on in minimum required version of the ROM or later.
  248.     // The system records the version number in a feature.  A feature is a
  249.     // piece of information which can be looked up by a creator and feature
  250.     // number.
  251.     FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
  252.     if (romVersion < requiredVersion) {
  253.         // If the user launched the app from the launcher, explain
  254.         // why the app shouldn't run.  If the app was contacted for something
  255.         // else, like it was asked to find a string by the system find, then
  256.         // don't bother the user with a warning dialog.  These flags tell how
  257.         // the app was launched to decided if a warning should be displayed.
  258.         if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) {
  259.             FrmAlert(RomIncompatibleAlert);
  260.         
  261.             // Pilot 1.0 will continuously relaunch this app unless we switch to 
  262.             // another safe one.  The sysFileCDefaultApp is considered "safe".
  263.             if (romVersion < 0x02000000) {
  264.                 AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
  265.             }
  266.         }
  267.         
  268.         return sysErrRomIncompatible;
  269.     }
  270.  
  271.     return 0;
  272. }
  273.  
  274. /* ---------------------------------------------------------------------------    */
  275.  
  276. static Boolean AppStart(void)
  277. {    
  278.     Err err;
  279.     
  280.     // Figure out which serial driver is on the system (old or new)
  281.     err = FtrGet(sysFileCSerialMgr, 1, &gUseNewSerialManager);
  282.     if (err) {
  283.         gUseNewSerialManager = 0;
  284.     }
  285.  
  286.     // Find the serial library.
  287.     err = PrvSerLibFind(&gRefNum);
  288.     
  289.     // If error loading library or library was not found
  290.     if ((err != 0) || (gRefNum == 0)) {
  291.         gRefNum = 0;
  292.     }
  293.     
  294.     // Open the library / serial port
  295.     else
  296.     {
  297.         err = PrvSerOpen(gRefNum, sysFileCVirtIrComm, 9600, &gRefNum);        
  298.         if (err != 0) {
  299.             gRefNum = 0;
  300.         }
  301.     }
  302.         
  303.     return (err == 0);
  304. }
  305.  
  306. /* ---------------------------------------------------------------------------    */
  307.  
  308. static void AppReceived(UInt8 *str, UInt32 size)
  309. {
  310.     /*UInt32 i, j = 0;
  311.     
  312.     for (i = 0 ; i < size ; i++) {
  313.         if (str[i] == '\r') {
  314.             if (str[i + 1] == '\n') {
  315.                 i++;
  316.             }
  317.             str[j++] = '\n';
  318.         }
  319.         else {
  320.             if (((str[i] >= ' ') && (str[i] < 0x80)) || (str[i] == '\n')) {
  321.                 str[j++] = str[i];
  322.             }
  323.         }
  324.     }            
  325.  
  326.     size = j;
  327.     
  328.     AppendEditFieldText(MainTextField, str, size);
  329.     FldRecalculateField(GetObjectPtr(MainTextField), true);
  330.     HandleTextScroll(100, MainTextField, MainTextScrollBar);
  331.     UpdateScrollBar(MainTextField, MainTextScrollBar);
  332.     */
  333. }
  334.  
  335. /* ---------------------------------------------------------------------------    */
  336.  
  337. static void AppReceive(void)
  338. {
  339.     UInt8    buffer[30];
  340.     Err        err;
  341.     UInt32    count;
  342.     UInt32    recvd = 1;    // Init to non-zero value for first pass thru while loop
  343.     
  344. #if 1
  345.     // Check to see if any data has arrived
  346.     err = PrvSerReceiveCheck(gRefNum, &count);
  347.  
  348.     // Read in the data a buffer (maximum) at a time
  349.     while (!err && count && recvd) {
  350.         recvd = PrvSerReceive(gRefNum, buffer, min(sizeof(buffer), count), 0, &err);
  351.         if (recvd) {
  352.             AppReceived(buffer, recvd);
  353.             count -= recvd;
  354.         }
  355.     }
  356. #else
  357.     // Read in all data that may have arrived
  358.     // This variation tests that a bug in SerReceive (returns data  even if less than requested)
  359.     // is fixed, but is not compatible with versions of the ROM without the bug fix.
  360.     while (recvd) {
  361.         recvd = PrvSerReceive(gRefNum, buffer, sizeof(buffer), 0, &err);
  362.         if (recvd) {
  363.             AppReceived(buffer, recvd);
  364.         }
  365.     }
  366. #endif
  367. }
  368.  
  369. /* ---------------------------------------------------------------------------    */
  370.  
  371. static void MainViewInit(void)
  372. {
  373.     FormPtr    form;
  374.  
  375.     // Get a pointer to the main form.
  376.     form = FrmGetActiveForm();
  377.     
  378.     // Draw the form.
  379.     FrmDrawForm(form);
  380. }
  381.  
  382. /* ---------------------------------------------------------------------------    */
  383.  
  384. static void MainViewSend(char    *str)
  385. {
  386.     Err        err;
  387. //    char    *str = FldGetTextPtr(GetObjectPtr(MainInputField));
  388.     UInt32    count, size = 0;
  389.     UInt8    buffer[101];
  390.     
  391.     if (str != 0) {
  392.         size = StrLen(str);
  393.     }
  394.     if (size == 0) {
  395.         // Send out the 4K test buffer
  396.         PrvSerSend(gRefNum, &gTestBuffer[0], sizeof(gTestBuffer), &err);
  397.         return;
  398.     }
  399.         
  400.     if (size > 100) {
  401.         size = 100;
  402.     }
  403.     MemMove(buffer, str, size);
  404.     buffer[size] = '\r';
  405.     size++;
  406.     
  407.     count = PrvSerSend(gRefNum, buffer, size, &err);
  408. }
  409.  
  410. /* ---------------------------------------------------------------------------    */
  411.  
  412. static Boolean MainViewHandleButton(EventPtr event)
  413. {
  414.     Boolean        handled = true;
  415.     
  416.     switch (event->data.ctlSelect.controlID) {
  417.         case MainStopButton:
  418.             MainViewSend(kStopCmd);
  419.             break;
  420.             
  421.         case MainPlayPauseButton:
  422.             MainViewSend(kPlayCmd);
  423.             break;
  424.             
  425.         case MainEjectButton:
  426.             MainViewSend(kEjectCmd);
  427.             break;
  428.             
  429.         case MainPrevButton:
  430.             MainViewSend(kPrevCmd);
  431.             break;
  432.             
  433.         case MainNextButton:
  434.             MainViewSend(kNextCmd);
  435.             break;
  436.             
  437.         case MainRewindButton:
  438.             MainViewSend(kRewindCmd);
  439.             break;
  440.             
  441.         case MainFFButton:
  442.             MainViewSend(kFastFwdCmd);
  443.             break;
  444.                         
  445.         default:
  446.             handled = false;
  447.             break;
  448.     }
  449.     
  450.     return handled;
  451. }
  452.  
  453. /* ---------------------------------------------------------------------------    */
  454.  
  455. static Boolean MainViewHandlePopup(EventPtr event)
  456. {
  457.     Boolean        handled = true;
  458. //    FieldPtr    field;
  459. //    char        buffer[30];
  460.     
  461.     switch (event->data.popSelect.listID) {
  462. /*        case MainCmdsList:
  463.             // Get corresponding mdm cmd text and put it into the send 'buffer'
  464.             SysStringByIndex(ModemCmdsStringList, event->data.popSelect.selection, buffer, sizeof(buffer));
  465.             SetEditFieldText(0, MainInputField, (unsigned char*)buffer, StrLen(buffer));
  466.             field = GetObjectPtr(MainInputField);
  467.             FldRecalculateField(field, true);
  468.             FrmSetFocus(FrmGetActiveForm(), FrmGetObjectIndex(FrmGetActiveForm(), MainInputField));
  469.             FldSetSelection(field, 0, FldGetTextLength(field));
  470.             break;
  471. */            
  472.         default:
  473.             handled = false;
  474.             break;
  475.     }
  476.     
  477.     return handled;
  478. }
  479.  
  480. /* ---------------------------------------------------------------------------    */
  481.  
  482. static Boolean MainViewHandleEvent(EventPtr event)
  483. {
  484.     Boolean        handled = false;
  485.     FormPtr        form;
  486.  
  487.     switch (event->eType) {
  488.            case ctlSelectEvent:  // A control button was pressed and released.
  489.             handled = MainViewHandleButton(event);
  490.             break;
  491.         
  492.         case popSelectEvent:  // An item was selected from a popup list
  493.             handled = MainViewHandlePopup(event);
  494.             break;
  495.       
  496.         case keyDownEvent:
  497.             switch(event->data.keyDown.chr)
  498.             {
  499.                 case pageUpChr:
  500.                     
  501.                     handled = true;
  502.                     break;
  503.                 
  504.                 case pageDownChr:
  505.                     
  506.                     handled = true;
  507.                     break;
  508.             }
  509.             break;
  510.             
  511.         case sclRepeatEvent:
  512. //            HandleTextScroll(event->data.sclRepeat.newValue - event->data.sclRepeat.value, MainTextField, MainTextScrollBar);
  513.             break;
  514.                 
  515.           case frmOpenEvent:    // The form was told to open.
  516.               // Initialize the main form.
  517.             MainViewInit();
  518.             handled = true;
  519.             break;
  520.             
  521.         case menuEvent:        // A menu item was selected.
  522.             // The “get info” being the only menu item, display the info form.            
  523.             // First clear the menu status from the display.
  524.             MenuEraseStatus(0);
  525.             
  526.             // Load the info form, then display it.
  527.             form = FrmInitForm(IrCommTestInfoForm);
  528.             FrmDoDialog(form);
  529.             
  530.             // Delete the info form.
  531.              FrmDeleteForm(form);
  532.             handled = true;
  533.             break;
  534.         }
  535.         
  536.     return handled;
  537. }
  538.  
  539. /* ---------------------------------------------------------------------------    */
  540.  
  541. static Boolean AppHandleEvent(EventPtr event)
  542. {
  543.     FormPtr    form;
  544.     Int16        formID;
  545.     Boolean    handled = false;
  546.  
  547.     if (event->eType == frmLoadEvent) {
  548.         // Load the form resource specified in the event then activate the form.
  549.         formID = event->data.frmLoad.formID;
  550.         form = FrmInitForm(formID);
  551.         FrmSetActiveForm(form);
  552.  
  553.         // Set the event handler for the form.  The handler of the currently 
  554.         // active form is called by FrmDispatchEvent each time it receives an event.
  555.         switch (formID) {
  556.             case MainForm:
  557.                 FrmSetEventHandler(form, MainViewHandleEvent);
  558.                 break;
  559.                 
  560. #ifdef FIXME
  561.             case kTraceDialogID:
  562.                 FrmSetEventHandler(form, TraceHandleEvent);
  563.                 break;
  564. #endif
  565.         }
  566.         
  567.         handled = true;
  568.     }
  569.     
  570.     return handled;
  571. }
  572.  
  573. /* ---------------------------------------------------------------------------    */
  574.  
  575. static void AppEventLoop(void)
  576. {
  577.     EventType event;
  578.     UInt16 error;
  579.     
  580.     do {
  581.         // Get the next available event.
  582.         EvtGetEvent(&event, sysTicksPerSecond);
  583.         AppReceive();
  584.         
  585.         if (!SysHandleEvent(&event))
  586.             if (!MenuHandleEvent(0, &event, &error))
  587.                 if (!AppHandleEvent(&event))
  588.                     FrmDispatchEvent(&event);
  589.     } while (event.eType != appStopEvent);
  590. }
  591.  
  592. /* ---------------------------------------------------------------------------    */
  593.  
  594. static void AppStop(void)
  595. {    
  596.     if (gRefNum != 0) {
  597.         PrvSerClose(gRefNum);
  598.     }
  599.         
  600.     FrmCloseAllForms();
  601. }
  602.  
  603. /* ---------------------------------------------------------------------------    */
  604.  
  605. UInt32 PilotMain(UInt16 cmd, Ptr /*cmdPBP*/, UInt16 launchFlags)
  606. {
  607.     Err    err;
  608.     
  609.     // This app makes use of PalmOS 3.0 features.  It will crash if
  610.     // run on an earlier version of PalmOS.  Detect and warn if this happens,
  611.     // then exit.
  612.     if ((err = AppRomVersionCompatible(version30, launchFlags)) != 0)
  613.         return err;
  614.  
  615.     switch (cmd)
  616.     {
  617.         // Check for a normal launch.
  618.         case sysAppLaunchCmdNormalLaunch:
  619.             // Initialize the application's global variables and database.
  620.             if (AppStart())
  621.             {
  622.                 // Start the first form.
  623.                 FrmGotoForm(MainForm);
  624.                     
  625.                 // Start the event loop.
  626.                 AppEventLoop();
  627.             }    
  628.                     
  629.             // Clean up before exiting the application.
  630.             AppStop();
  631.             break;
  632.                     
  633.         case sysAppLaunchCmdSaveData:
  634.             FrmSaveAllForms();
  635.             break;
  636.     }
  637.     
  638.     return 0;
  639. }
  640.